/*
 * FileName：WxAccountInterceptor.java 
 * <p>
 * Copyright (c) 2017-2020 <a href="https://www.smartwx.info">hermit(1154808491@qq.com)</a>.
 * <p>
 * Licensed under the GNU General Public License, Version 3 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.gnu.org/licenses/gpl-3.0.html
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */
package com.smart.wx.common.interceptor;

import com.smart.common.annotation.WxAccount;
import com.smart.common.util.StringUtil;
import com.smart.common.util.WxMemoryCacheClient;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;

import java.lang.reflect.InvocationTargetException;
import java.util.Properties;

/**
 * 拦截器作用：给各实体对象在增加、修改时，自动添加操作属性信息。
 */

@Intercepts(value = {
        @Signature(type = Executor.class,
                method = "update",
                args = {MappedStatement.class, Object.class}),
        @Signature(type = Executor.class,
                method = "query",
                args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class,
                        CacheKey.class, BoundSql.class}),
        @Signature(type = Executor.class,
                method = "query",
                args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})})
public class WxAccountInterceptor implements Interceptor {

    public Object intercept(Invocation invocation) throws Throwable {
        Object[] args = invocation.getArgs();

        //遍历处理所有参数，update方法有两个参数，参见Executor类中的update()方法。
        for (int i = 0; i < args.length; i++) {
            Object arg = args[i];
            if(null!=arg){
                WxAccount annotation = arg.getClass().getAnnotation(WxAccount.class);
                if (null != annotation) {
                    setProperty(arg);
                }
            }
        }
        return invocation.proceed();
    }
    /**
     * 为对象的操作属性赋值
     *
     * @param obj
     */
    private void setProperty(Object obj) throws Exception {
        try {
            if (StringUtil.isBlank(BeanUtils.getProperty(obj, "account"))) {
                BeanUtils.setProperty(obj, "account", WxMemoryCacheClient.getAccount());
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }
    public void setProperties(Properties properties) {

    }

}
